// cmd/root.go
package cmd

import (
	"fmt"
	"os"
	"path/filepath"
	"strings"

	"github.com/spf13/cobra"
)

const AppVersion = "1.0.0"

var (
	multiSizeFlag      bool
	customSizeFlags    []uint
	coverFlag          bool
	filterFileTypesStr []string
)

var rootCmd = &cobra.Command{
	Use:   "i2i",
	Short: "Convert images to Windows ICO format",
	Long:  `A command-line tool for converting common image formats into Windows .ico files.`,
	Args:  cobra.ArbitraryArgs, // 允许任意数量的位置参数
	RunE: func(cmd *cobra.Command, args []string) error {
		if len(args) == 0 {
			return fmt.Errorf("Usage: i2i <img> [ico]")
		}

		src := args[0]
		dst := ""
		if len(args) > 1 {
			dst = args[1]
		}

		// pixels
		sizes := []uint{256}
		if multiSizeFlag {
			sizes = []uint{16, 24, 32, 48, 64, 96, 128, 256, 512}
		} else {
			if len(customSizeFlags) == 0 {
				customSizeFlags = []uint{256}
			}
			sizes = customSizeFlags
		}
		for i := range sizes {
			if sizes[i] > 512 {
				sizes[i] = 512
			}
		}
		sizes = DeduplicateUintSlice(sizes, 1)
		fmt.Println("🎛️ output sizes:", sizes)

		// 使用基于 filepath 扩展的函数来获取可能的输入文件列表
		inputFilePathList, err := ExpandWildcardsWithFilter(src, filterFileTypesStr)
		if err != nil {
			return err
		}
		if len(inputFilePathList) == 0 {
			return fmt.Errorf("❌  未找到任何匹配的输入文件: %s", src)
		}

		total := len(inputFilePathList)
		success := 0

		for _, srcFile := range inputFilePathList {
			srcBase := strings.Split(filepath.Base(srcFile), ".")[0]
			dstFile := ""

			if total == 1 {
				if dst == "" {
					dstFile = srcBase + ".ico"
				} else {
					dstExt := filepath.Ext(dst)
					if dstExt == "" {
						dstFile = filepath.Join(dst, srcBase+".ico")
					} else {
						dstFile = dst
						if strings.HasSuffix(dst, "/") || strings.HasSuffix(dst, "\\") {
							dstFile = filepath.Join(dst, srcBase+".ico")
						}
					}
				}
			} else {
				if dst == "" {
					dstFile = srcBase + ".ico"
					if multiSizeFlag {
						dstFile = filepath.Join("out", dstFile)
					}
				} else {
					dstFile = filepath.Join(dst, srcBase+".ico")
				}
			}

			finalOutPutFile, err := doConvert(srcFile, dstFile, sizes, coverFlag)
			if err != nil {
				fmt.Printf("❌  convert: [%s] -> [%s] err: %v \n", srcFile, dstFile, err.Error())
			} else {
				fmt.Printf("✅  convert: [%s] -> [%s] \n", srcFile, finalOutPutFile)
				success++
			}
		}

		percent := PercentText(success, total)
		if success > 0 {
			fmt.Printf("✨  %s %d/%d files converted successfully \n", percent, success, total)
		} else {
			fmt.Printf("❌  %d/%d no files converted \n", success, total)
		}

		return nil
	},
}

// 添加 how 子命令
var howCmd = &cobra.Command{
	Use:   "how",
	Short: "Show usage examples",
	Run: func(cmd *cobra.Command, args []string) {
		fmt.Println("Examples:")
		fmt.Println("[1] convert image to ico (default 256x256):   i2i test.png")
		fmt.Println("[4] convert image to ico with all sizes:      i2i -m test.png")
		fmt.Println("[2] convert image to ico with specifier name: i2i test.png new.ico")
		fmt.Println("[3] convert image to ico with output dir:     i2i test.png out")
		fmt.Println("[5] convert images to ico:                    i2i *.png")
		fmt.Println("[6] convert images to ico with output dir:    i2i *.png out")
		fmt.Println("[7] convert images to ico with all sizes:     i2i -m *.png")
		fmt.Println("[8] convert images to ico with custom size:   i2i -s 128 -s 256 *.png")
	},
}

func Execute() {
	if err := rootCmd.Execute(); err != nil {
		fmt.Fprintf(os.Stderr, "%v\n", err)
		os.Exit(1)
	}
}

func init() {
	rootCmd.PersistentFlags().BoolVarP(&multiSizeFlag, "multi", "m", false, "generate all pixels [16, 24, 32, 48, 64, 96, 128, 256, 512]")
	rootCmd.PersistentFlags().UintSliceVarP(&customSizeFlags, "size", "s", []uint{256}, "set output pixels [16, 24, 32, 48, 64, 96, 128, 256, 512]. default is 256, max is 512.")
	rootCmd.PersistentFlags().StringArrayVarP(&filterFileTypesStr, "type", "t", []string{"png", "jpg", "jpeg"}, "file types to filter when using wildcard pattern")
	rootCmd.PersistentFlags().BoolVarP(&coverFlag, "cover", "c", true, "cover existed files when write output files")

	rootCmd.AddCommand(howCmd)

	// 👇 可选：移除自动添加的 help 子命令
	//rootCmd.SetHelpCommand(&cobra.Command{Hidden: true})
}
